home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-12-22 | 19.7 KB | 683 lines | [TEXT/CWIE] |
- /*
- File: Sample.c
-
- Contains: Location Manager SDK Sample main code...
-
- Version: ALM SDK 2.0
- Package: Location Manager SDK 2.0
-
- Copyright: © 1996-1997 by Apple Computer, Inc.
- All rights reserved.
-
- Bugs?: Please include the the file and version information (from above) with
- the problem description. Developers belonging to one of the Apple
- developer programs can submit bug reports to:
-
- devsupport@apple.com
-
- */
-
- // -------------------------------------------------------------------------------------------------
-
- #include <ConditionalMacros.h>
-
- // We recommend using the most updated headers currently available; at this writing, that is
- // Universal Headers 3.0.1. More recent editions should work as well; if you want to use older
- // headers for some reason, it should be possible, but you're on your own and other parts of this
- // sample may need to change...
-
- #if !defined (UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0301)
-
- #error "Please use header files 3.0.1 or newer"
-
- #endif // updated headers...
-
- // Having gotten _that_ out of the way, let's be sure that nobody fiddled with the project
- // settings by accident...
-
- #if !TARGET_CPU_68K | TARGET_RT_MAC_CFM
-
- #error This project MUST be classic 68K!
-
- #endif // not 68K classic build
-
- // -------------------------------------------------------------------------------------------------
-
- // Module Include...
-
- #include "EjectPCCardModule.h"
-
- // MacOS Includes...
-
- #define ALM_BASENAME()
-
- #include <Components.h>
- #include <Fonts.h>
- #include <LocationManager.k.h>
- #include <PLStringFuncs.h>
- #include <Resources.h>
- #include <TextUtils.h>
-
- // -------------------------------------------------------------------------------------------------
-
- // Module-specific defines...
-
- #define kModuleVersion 1
-
- // -------------------------------------------------------------------------------------------------
-
- // Readability Constants...
-
- #define kInvalidFunction ((ComponentFunctionUPP) -1)
-
- #define kDefaultINTLresources NULL
- #define kNoSeconds false
-
- #define kAllocateMemory NULL
- #define kPlaceInFront (WindowPtr)-1
-
- #define kUseStandardFilterProc NULL
-
- // -------------------------------------------------------------------------------------------------
-
- // Local prototypes...
-
- static Boolean
- CallSupported (SInt16 selector);
- // Return true if the specified selector code is one this module supports...
- static ComponentResult
- HandleComponentManagerCall (ComponentParameters* params, SInt16 selector);
- // Dispatch a component manager call (selector < 0)...
- static ComponentResult
- HandleLocationManagerCall (ComponentParameters* params, SInt16 selector);
- // Dispatch a Location Manager specific call...
-
- // Component prototypes...
-
- static pascal ComponentResult
- Open (ComponentInstance self);
- // Initialize the modules's global variables, etc...
- static pascal ComponentResult
- Close (ComponentInstance self);
- // Deinitialize the modules's global variables...
-
- OSErr Call_ResourcePPC (ResType pResType, short pResID, long params);
-
- // -------------------------------------------------------------------------------------------------
-
- // Main entry point (interface as expected by component manager)...
-
- pascal ComponentResult
- main (ComponentParameters* params, Handle storage) {
-
- #ifndef __SC__
- #pragma unused (storage)
- #endif // __SC__
-
- // We dispatch the calls from here; also, for ALM calls, we'll make sure the current
- // resource fork is ours...
-
- ComponentResult result;
- SInt16 selector = params->what;
-
- if (selector < 0) {
- // Component manager request codes are negative...
- result = HandleComponentManagerCall (params, selector);
- } else {
- // ALM selectors...
- result = HandleLocationManagerCall (params, selector);
- } // if
-
- return result;
-
- } // main
-
- // -------------------------------------------------------------------------------------------------
-
- static Boolean
- CallSupported (SInt16 selector) {
-
- Boolean response;
-
- switch (selector) {
- case kALMGetCurrentSelect:
- case kALMSetCurrentSelect:
- case kALMCompareSettingSelect:
- case kALMDescribeSettingSelect:
- case kALMDescribeErrorSelect:
- case kALMEditSettingSelect:
- case kALMGetInfoSelect:
- case kALMGetScriptInfoSelect:
- response = true;
- break;
- default:
- response = false;
- break;
- } // switch
-
- return response;
-
- } // CallSupported
-
- // -------------------------------------------------------------------------------------------------
-
- static ComponentResult
- HandleComponentManagerCall (ComponentParameters* params, SInt16 selector) {
-
- ComponentResult result = (ComponentResult) noErr;
- ComponentFunctionUPP func = NULL;
-
- switch (selector) {
-
- case kComponentOpenSelect:
- func = (ComponentFunctionUPP) Open;
- break;
- case kComponentCloseSelect:
- func = (ComponentFunctionUPP) Close;
- break;
- case kComponentCanDoSelect:
- result = CallSupported (*(SInt16*) params->params);
- break;
- case kComponentVersionSelect:
- result = kModuleVersion;
- break;
- case kComponentRegisterSelect:
- result = false; // false means "yes, please register me"
- break;
- case kComponentTargetSelect :
- case kComponentUnregisterSelect :
- result = badComponentSelector;
- break;
-
- } // switch
-
- if (func != NULL) {
- result = CallComponentFunction (params, func);
- } // if
-
- return result;
-
- } // HandleComponentManagerCall
-
- // -------------------------------------------------------------------------------------------------
-
- static ComponentResult
- HandleLocationManagerCall (ComponentParameters* params, SInt16 selector) {
-
- ComponentResult result = (ComponentResult) noErr;
- ComponentFunctionUPP func = NULL;
-
- switch (selector) {
-
- case kALMGetCurrentSelect:
- func = (ComponentFunctionUPP) GetCurrent;
- break;
- case kALMSetCurrentSelect:
- func = (ComponentFunctionUPP) SetCurrent;
- break;
- case kALMCompareSettingSelect:
- func = (ComponentFunctionUPP) CompareSetting;
- break;
- case kALMEditSettingSelect:
- func = (ComponentFunctionUPP) EditSetting;
- break;
- case kALMDescribeSettingSelect:
- func = (ComponentFunctionUPP) DescribeSetting;
- break;
- case kALMDescribeErrorSelect:
- func = (ComponentFunctionUPP) DescribeError;
- break;
- case kALMGetScriptInfoSelect:
- func = (ComponentFunctionUPP) GetScriptInfo;
- break;
- case kALMGetInfoSelect:
- func = (ComponentFunctionUPP) GetInfo;
- break;
- default:
- func = kInvalidFunction;
- break;
-
- } // switch
-
- if (func == kInvalidFunction) {
- result = badComponentSelector;
- } else if (func != NULL) {
- result = CallComponentFunction (params, func);
- } // if
-
- return result;
-
- } // HandleLocationManagerCall
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- Open (ComponentInstance self) {
-
- // Keep the Open routine lightweight, and only fail in the case of dire
- // emergencies that indicate a major problem; under ALM 2.0, you might wish to return an
- // error here to quietly suppress your module from being usable--for example if you require
- // Infrared hardware found only on some models of computer--but it is generally better to
- // _succeed_ here and describe an _error_ from your GetCurrent call...
-
- // Since we are an action module, we have no state to remember. The only thing we
- // need to keep track of is our resource fork refnum so that we can get our resources if
- // needed. No need for a complicated globals structure for that, it fits nicely into
- // 32 bits (with 16 to spare), so just set our instance storage to our resource refnum.
- SetComponentInstanceStorage (self, (Handle)OpenComponentResFile ((Component) self));
-
- return (ComponentResult) ResError ();
-
- } // Open
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- Close (ComponentInstance self) {
-
- // Always make sure to close your resource fork before exiting a component, otherwise
- // really bad things will happen to the foreground application.
- CloseComponentResFile ((short)GetComponentInstanceStorage (self));
-
- return (ComponentResult) noErr;
-
- } // Close
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetCurrent (Handle setting) {
-
- OSErr err = noErr;
- long attributes;
-
- // Make sure that the system has PC Card Manager 3.0 or later installed so that we don't
- // run on a system that a) isn't PPC, and b) doesn't support the PC Card 3.0 API.
- err = Gestalt (gestaltPCCard, &attributes);
- if (err == noErr && !(attributes & (1L << gestaltPCCardFamilyPresent))) {
- // Return a descriptive error, "We require PC Card Manager 3.0 or later"
- err = kNeedPCCard3Err;
- } else if (err == gestaltUndefSelectorErr) {
- // Return a descriptive error, "This machine doesn't even support PC Cards"
- err = kNeedPCCardsErr;
- }
-
- if (err == noErr) {
- SetHandleSize ((Handle) setting, sizeof (SettingRec));
- err = MemError ();
- }
-
- if (err == noErr) {
- (**(SettingHandle)setting).version = kModuleVersion;
- (**(SettingHandle)setting).slot = kNoSlotsID;
- }
-
- return (ComponentResult) err;
-
- } // GetCurrent
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- SetCurrent (Handle setting, ALMRebootFlags* flags) {
-
- OSErr err = noErr;
- long attributes;
-
- // Hopefully this code won't ever detect that we are on an unsupported system, but perhaps
- // the user might have imported a setting from a PowerBook to a desktop machine, and we don't
- // want to crash.
-
- // Make sure that the system has PC Card Manager 3.0 or later installed so that we don't
- // run on a system that a) isn't PPC, and b) doesn't support the PC Card 3.0 API.
- err = Gestalt (gestaltPCCard, &attributes);
- if (err == noErr && !(attributes & (1L << gestaltPCCardFamilyPresent))) {
- // Return a descriptive error, "We require PC Card Manager 3.0 or later"
- err = kNeedPCCard3Err;
- } else if (err == gestaltUndefSelectorErr) {
- // Return a descriptive error, "This machine doesn't even support PC Cards"
- err = kNeedPCCardsErr;
- }
-
- // Call a PPC code resource to walk the name registry and eject the desired PC Cards.
- err = Call_ResourcePPC (kPPCCodeResource, kPPCCodeResourceID, (**(SettingHandle)setting).slot);
-
- if (err == noErr) {
- // It either worked and everything is cool...
- *flags = kALMAvailableNow;
- } else {
- // ... or we didn't eject anything and so things remain as they were.
- *flags = kALMNoChange;
- }
-
- return (ComponentResult) err;
-
- } // SetCurrent
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- CompareSetting (Handle setting1, Handle setting2, Boolean* equal) {
-
- // A simple compare tells us if the two settings are the same.
- *equal = ((**(SettingHandle)setting1).slot == (**(SettingHandle)setting2).slot);
-
- return (ComponentResult) noErr;
-
- } // CompareSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- EditSetting (Handle setting) {
-
- OSErr err = noErr;
- UInt32 savedA5;
- QDGlobals mqd; // So we can put up an alert...
- QDGlobalsPtr moduleQuickdraw = &mqd;
- DialogPtr theDialog = NULL;
-
- // In ALM 2.0, if you don't support EditSetting, the control panel will display a default
- // error message if the user tries to edit your setting. Of course, how to edit the setting
- // is entirely dependant on the content of the setting. In the case of this sample, we
- // really don't know what the meaning of the preference file is, but we can, at the very least,
- // give the user a more helpful error message...
-
- savedA5 = SetA5 ((UInt32) &moduleQuickdraw);
-
- // Initialize a QD world...
-
- InitGraf (&mqd.thePort); // always init _our_ QD structure
- InitFonts ();
- InitWindows ();
- InitMenus ();
- TEInit ();
- InitDialogs (NULL);
- InitCursor ();
-
- // Get and display the "which PC Card slot" dialog...
-
- theDialog = GetNewDialog (kEditMessageRsrcID, kAllocateMemory, kPlaceInFront);
-
- if (theDialog != NULL) {
-
- SInt16 itemHit;
- GrafPtr svPort;
- short itemType;
- ControlHandle item;
- Rect box;
-
- GetPort (&svPort);
- SetPort (theDialog);
- SetDialogDefaultItem (theDialog, kEditOKButton);
- SetDialogCancelItem (theDialog, kEditCancelButton);
-
- if ((**(SettingHandle)setting).slot == kLowerSlotID || (**(SettingHandle)setting).slot == kBothSlotsID) {
- GetDialogItem (theDialog, kLowerPCCardCheckBox, &itemType, &(Handle)item, &box);
- SetControlValue (item, 1);
- }
-
- if ((**(SettingHandle)setting).slot == kUpperSlotID || (**(SettingHandle)setting).slot == kBothSlotsID) {
- GetDialogItem (theDialog, kUpperPCCardCheckBox, &itemType, &(Handle)item, &box);
- SetControlValue (item, 1);
- }
-
- ShowWindow (theDialog);
-
- // Loop until closed; note that, as long as we use the standard filter proc,
- // the ALM control panel will manage launches and moveable-modal things for us...
-
- do {
- ModalDialog (kUseStandardFilterProc, &itemHit);
- switch (itemHit) {
- case kEditCancelButton:
- err = userCanceledErr;
- break;
- case kEditOKButton:
- err = noErr;
- break;
- case kUpperPCCardCheckBox:
- case kLowerPCCardCheckBox:
- GetDialogItem (theDialog, itemHit, &itemType, &(Handle)item, &box);
- if (itemType == chkCtrl + ctrlItem) {
- SetControlValue (item, !GetControlValue (item));
- }
- break;
- } // switch
- } while (itemHit != kEditCancelButton && itemHit != kEditOKButton);
-
- if (err == noErr) {
- short lower, upper;
-
- SetHandleSize ((Handle) setting, sizeof (SettingRec));
- err = MemError ();
-
- if (err == noErr) {
- GetDialogItem (theDialog, kLowerPCCardCheckBox, &itemType, &(Handle)item, &box);
- lower = GetControlValue (item);
-
- GetDialogItem (theDialog, kUpperPCCardCheckBox, &itemType, &(Handle)item, &box);
- upper = GetControlValue (item);
-
- if (upper && lower) {
- (**(SettingHandle)setting).slot = kBothSlotsID;
- } else if (lower) {
- (**(SettingHandle)setting).slot = kLowerSlotID;
- } else if (upper) {
- (**(SettingHandle)setting).slot = kUpperSlotID;
- } else {
- // If nothing was checked, then the user doesn't need our module.
- (**(SettingHandle)setting).slot = kNoSlotsID;
- err = kModuleNotNeededErr;
- }
- }
- }
-
- DisposeDialog (theDialog);
- SetPort (svPort);
-
- } else {
-
- err = resNotFound;
-
- } // if
-
- // Restore a5...
-
- (void) SetA5 (savedA5);
-
- return (ComponentResult) err;
-
- } // EditSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- DescribeSetting (Handle setting, CharsHandle text) {
-
- OSErr err = noErr;
- Str255 settingDescription;
-
- // Get the description strings "Neither slot", "Both slots", "Upper slot", "Lower slot"
- // The STR# resource is laid out so that our setting's slot+2 value gets the correct resource.
- GetIndString (settingDescription, kDescribeSettingStrings, (**(SettingHandle)setting).slot + 2);
- err = ResError ();
-
- if (err == noErr && settingDescription[0] == 0) {
- err = resNotFound;
- }
-
- if (err == noErr) {
- SetHandleSize (text, settingDescription[0]);
- err = MemError ();
- }
-
- if (err == noErr) {
- BlockMoveData (&(settingDescription[1]), *text, settingDescription[0]);
- }
-
- return (ComponentResult) err;
-
- } // DescribeSetting
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- DescribeError (OSErr lastErr, Str255 errStr) {
-
- OSErr err = noErr;
- short stringID;
-
- // Get the error requested. I'm not sure if we will ever get the resNotFound error, but
- // just in case, we have a description of what it means.
-
- switch (lastErr) {
- case resNotFound:
- stringID = kDescribeResNotFound;
- break;
- case kModuleNotNeededErr:
- stringID = kDescribeNotNeeded;
- break;
- case kNeedPCCard3Err:
- stringID = kDescribeNeedPCCard3;
- break;
- case kNeedPCCardsErr:
- stringID = kDescribeNeedPCCards;
- break;
- }
-
- GetIndString (errStr, kDescribeErrorStrings, stringID);
- err = ResError ();
-
- if (err == noErr && errStr[0] == 0) {
- err = resNotFound;
- }
-
- if (lastErr == err) {
- // Don't get stuck in a loop...
- // I'm not sure if the Location Manager checks this or not, but better safe then sorry.
- // Basically this prevents a never ending stream of resNotFound errors.
- err = noErr;
- }
-
- return (ComponentResult) err;
-
- } // DescribeError
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetScriptInfo (ALMScriptManagerInfo* info) {
-
- OSErr err = noErr;
- ALMAltScriptManagerInfoHandle scriptInfo = NULL;
-
- // We stored this stuff in a resource, so it can be localized easily; we have to do a bit of
- // translation, though, from the alternate format to the ALM format (fortunately
- // the alternate format is given to us in the headers!)...
-
- scriptInfo = (ALMAltScriptManagerInfoHandle)
- GetResource (kALMAltScriptManagerInfoRsrcType, kALMAltScriptManagerInfoRsrcID);
-
- if (scriptInfo != NULL) {
-
- HLock ((Handle) scriptInfo);
-
- info->version = (**scriptInfo).version;
- info->scriptCode = (**scriptInfo).scriptCode;
- info->regionCode = (**scriptInfo).regionCode;
- info->langCode = (**scriptInfo).langCode;
- info->fontSize = (**scriptInfo).fontSize;
- GetFNum ((**scriptInfo).fontName, &info->fontNum);
-
- HUnlock ((Handle) scriptInfo);
-
- } else {
- err = ResError ();
- } // if
-
- if (scriptInfo != NULL) {
- ReleaseResource ((Handle) scriptInfo);
- } // if
-
- return (ComponentResult) err;
-
- } // GetScriptInfo
-
- // -------------------------------------------------------------------------------------------------
-
- static pascal ComponentResult
- GetInfo (CharsHandle* text, STHandle* style, ModalFilterUPP filter) {
-
- #ifndef __SC__
- #pragma unused (filter)
- #endif // __SC__
-
- OSErr err = noErr;
-
- // This code is pretty cookie-cutter, unless you want to make it context-sensitive...
-
- do {
-
- *text = (CharsHandle) Get1Resource ('TEXT', kGetInfoRsrcID);
- err = ResError ();
- if (err != noErr) {
- break;
- } else if (*text == NULL) {
- err = resNotFound;
- break;
- } // if
- *style = (STHandle) Get1Resource ('styl', kGetInfoRsrcID);
- err = ResError ();
- if (err != noErr) {
- break;
- } else if (*style == NULL) {
- err = resNotFound;
- break;
- } // if
- DetachResource ((Handle) *text);
- DetachResource ((Handle) *style);
-
- } while (false); // execute once...
-
- return (ComponentResult) err;
-
- } // GetInfo
-
- // -------------------------------------------------------------------------------------------------
-
- // The code needed to call a PPC code resource from 68K code (which is what the component is).
- OSErr Call_ResourcePPC (ResType pResType, short pResID, long params)
- {
- Handle resCodeHdl = Get1Resource(pResType,pResID); // Get the resource
- SInt32 result;
- OSErr myErr = noErr;
-
- if (resCodeHdl) // Did we find it?
- {
- ResourceProcUPP tResourceProcUPP;
-
- HLockHi(resCodeHdl); // Lock it high
-
- if (*(UInt16*) *resCodeHdl == _MixedModeMagic) // If it's already a routine descriptor
- tResourceProcUPP = (ResourceProcUPP) *resCodeHdl; // just dereference it
- else // otherwise
- tResourceProcUPP = NewResourceProcPPC(*resCodeHdl); // create a routine descriptor
-
- result = CallResourceProc(tResourceProcUPP, params);// Call it
-
- if (*(UInt16*) *resCodeHdl != _MixedModeMagic) // If it wasn't a routine descriptor
- DisposeRoutineDescriptor(tResourceProcUPP); // Dispose of the one we created
-
- HUnlock(resCodeHdl); // Unlock and
- ReleaseResource(resCodeHdl); // release the resource
- }
- else // Didn't find it
- {
- myErr = ResError(); // Get resource error
- if (myErr == noErr) // If its noErr
- myErr = resNotFound; // assume resource not found
- }
- return myErr; // return error
- }
-